package com.hjy.elasticsearch.service.impl;

import cn.hutool.core.util.StrUtil;
import com.hjy.elasticsearch.entity.ProductEntity;
import com.hjy.elasticsearch.myEnum.ProductTypeEnum;
import com.hjy.elasticsearch.service.MyESService;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Search;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @CopyRight: 版权所有
 * @Author: hejinyi
 * @Description:
 * @Date: 2020/12/1
 */
@Service
public class MyESServiceImpl implements MyESService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyESServiceImpl.class);
    @Autowired
    private JestClient jestClient;

    @Value("${OTS.tenantId}")
    private String tenantId;


    /**
     *
     * @param searchContent 搜索关键字
     * @param productType 产品类型
     * @return
     */
    public List<ProductEntity> searchProduct(String searchContent,String productType,int num){
        LOGGER.info("搜索产品.....searchContent={},productType={},num={}",searchContent,productType,num);
        List<ProductEntity> list = new ArrayList();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        QueryBuilder is_selling = QueryBuilders.termQuery("is_selling", 1);
        boolQuery.must(is_selling);
//        QueryBuilder is_pack = QueryBuilders.termQuery("is_pack", 1);
//        boolQuery.should(is_pack);
        QueryBuilder is_deleted = QueryBuilders.termQuery("is_deleted", 0);
        boolQuery.must(is_deleted);
        QueryBuilder is_visible = QueryBuilders.termQuery("is_visible", 0);
        boolQuery.must(is_visible);
        QueryBuilder is_power = QueryBuilders.termQuery("is_power", 1);
        boolQuery.should(is_power);
        QueryBuilder tenantIdBuilder = QueryBuilders.termQuery("tenant_id", tenantId);
        boolQuery.must(tenantIdBuilder);

        if(StrUtil.isNotBlank(searchContent)){
            LOGGER.info("根据产品名称查询..........{}",searchContent);
            QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery("product_name", searchContent);
            boolQuery.must(queryBuilder1);
        }
        QueryBuilder queryBuilder2 = null;
        if(StrUtil.isNotBlank(productType)){
            if(productType.equals("4")){
                productType = ProductTypeEnum.SPECIALTY_PRODUCT.getCode()+"";
            }
            if(productType.equals("5")){
                productType = ProductTypeEnum.LINE_PRODUCT.getCode()+"";
            }
            LOGGER.info("根据产品类别查询..........{}",productType);
            queryBuilder2 = QueryBuilders.matchPhraseQuery("product_group_code", productType);
            boolQuery.must(queryBuilder2);
        }else{
            LOGGER.info("查询特产和线路..........");
            queryBuilder2 = QueryBuilders.termsQuery("product_group_code", ProductTypeEnum.SPECIALTY_PRODUCT.getCode().toString(),ProductTypeEnum.LINE_PRODUCT.getCode().toString());
            boolQuery.must(queryBuilder2);
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置起始页
        searchSourceBuilder.from(0);
        //设置页大小
        searchSourceBuilder.size(num);
        //设置查询条件
        searchSourceBuilder.query(boolQuery);

        LOGGER.info("搜索产品....."+searchSourceBuilder.toString());
        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex("*product*")
                .build();
        try {
            JestResult result = jestClient.execute(search);
            list = result.getSourceAsObjectList(ProductEntity.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return list;
    }

    @Override
    public List<ProductEntity> seachBody(String searchContent,String productType) {
        List<ProductEntity> list = new ArrayList();

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        QueryBuilder status = QueryBuilders.termQuery("status", 1);
        boolQuery.must(status);
        QueryBuilder is_deleted = QueryBuilders.termQuery("is_deleted", 0);
        boolQuery.must(is_deleted);
        QueryBuilder is_visible = QueryBuilders.termQuery("is_visible", 0);
        boolQuery.must(is_visible);
        QueryBuilder tenantIdBuilder = QueryBuilders.termQuery("tenant_id", tenantId);
        boolQuery.must(tenantIdBuilder);

        if (StrUtil.isNotBlank(searchContent)) {
            LOGGER.info("根据主体名称和描述查询..........{}", searchContent);
            QueryBuilder queryBuilder1 = QueryBuilders.matchPhraseQuery( "body_name",searchContent);
            QueryBuilder description = QueryBuilders.matchPhraseQuery( "description",searchContent);
            boolQuery.must(queryBuilder1);
            boolQuery.should(description);
        }
        if (StrUtil.isNotBlank(productType)) {
            LOGGER.info("根据主体类别查询..........{}", productType);
            QueryBuilder queryBuilder2 = QueryBuilders.matchPhraseQuery("body_type", productType);
            boolQuery.must(queryBuilder2);
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置起始页
        searchSourceBuilder.from(0);
        //设置页大小
        searchSourceBuilder.size(20);
        //设置查询条件
        searchSourceBuilder.query(boolQuery);


        LOGGER.info("..搜索主体...:"+searchSourceBuilder.toString());
        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex("body*")
                .build();
        try {
            JestResult result = jestClient.execute(search);
            //总条数
     //       int hitCount = result.getJsonObject().get("hits").getAsJsonObject().get("total").getAsInt();
            list = result.getSourceAsObjectList(ProductEntity.class);


        } catch (IOException e) {
            e.printStackTrace();
        }


        int num = 20;
        List bodylist = seachBodyStar(list);
        if(bodylist!=null){
            if(bodylist.size()>=num){
                return bodylist;
            }else{
                List productlist = searchProduct(searchContent,productType,num-bodylist.size());
                bodylist.addAll(productlist);
                return bodylist;
            }
        }else{
            List productlist = searchProduct(searchContent,productType,num);
            return productlist;
        }
    }

    /**
     * 查星级
     * @return
     */
    public List seachBodyStar(List<ProductEntity> param_list) {

        QueryBuilder queryBuilder = null;
        List<Long> bodyIds = new ArrayList<>();
        for(ProductEntity entity : param_list){
            bodyIds.add(entity.getId());
        }
        LOGGER.info("查询主体id.....", bodyIds.toArray().toString());
        queryBuilder = QueryBuilders.termsQuery("body_id", bodyIds);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);

        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex("*body_detail*")
                .build();
        try {
            JestResult result = jestClient.execute(search);
            List<ProductEntity> list = result.getSourceAsObjectList(ProductEntity.class);
            for(ProductEntity entity : param_list){
                for(ProductEntity starEntity : list){
                    if(starEntity.getBody_id().equals(entity.getId().toString())){
                        entity.setStar_type(starEntity.getStar_type());
                        entity.setBody_id(starEntity.getBody_id());
                    }
                }
            }
            return param_list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 查询条件
     * @param queryBuilder
     * @return
     */
    private <T> List<T> findMatchQueryBuilder(QueryBuilder queryBuilder, String ESIndex,String ESType,Class<T> type ){
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder).query();

//        //设置高亮
//        HighlightBuilder highlightBuilder = new HighlightBuilder();
//        // title 字段高亮
//        HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("product_name");
//        // 配置高亮类型
//        highlightTitle.highlighterType("unified");
//        // 添加到 builder
//        highlightBuilder.field(highlightTitle);
//        HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
//        highlightBuilder.field(highlightUser);
//        searchSourceBuilder.highlighter(highlightBuilder);

        LOGGER.info(".....1........: "+searchSourceBuilder.toString());

        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(ESIndex)
                //          .addType(ESType)
                .build();

        try {
            LOGGER.info(".......2......: "+search.toString());
            JestResult result = jestClient.execute(search);
            return result.getSourceAsObjectList(type);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
}
